﻿using System;
using System.Collections.Generic;
using Bastanteo.Dominio;
using Bastanteo.Persistencia;
using NUnit.Framework;

namespace Bastanteo.Pruebas
{
    [TestFixture]
    public class Test4_representanteDAO
    {
        IGrupoDAO grupoDAO = null;
        IClienteDAO clienteDAO = null;
        IRepresentanteDAO representanteDAO = null;

        Int32 NuevoGrupo = 0;
        Int32 NuevoRepresentante = 0;
        Grupo grupo = null;
        Cliente cliente = null;
        Representante representanteCreado = null;

        [TestFixtureSetUp]
        public void InicializarPruebas()
        {
            // Instanciamos la implementación elegida (ADO o NHibernate)

            grupoDAO = new Persistencia.NH.GrupoDAO();
            clienteDAO = new Persistencia.NH.ClienteDAO();

            representanteDAO = new Persistencia.NH.RepresentanteDAO();
            

            foreach (Representante representante in representanteDAO.ListarTodos())
                representanteDAO.Eliminar(representante);

            grupo = grupoDAO.Crear(new Grupo() { Descripcion="A" });
            NuevoGrupo = grupo.CodigoGrupo;

            cliente = clienteDAO.Crear(new Cliente() { CodigoCliente = 1, CantidadEmpleados = 4, FechaInicioOperaciones = DateTime.Now , RazonSocial="abc sac", Ruc="6565656565", TipoEmpresa="a"});
        }
        
        [Test]
        public void Test1_Crear()
        {
            // 1. Validar que ocurra un error al intentar crear un representante con un dato nulo
            Representante representanteACrear = new Representante();
            representanteACrear.TipoDocumento = "DNI";
            representanteACrear.NumeroDocumento = null;
            representanteACrear.Nombres = "Alexandra";
            representanteACrear.Apellidos = "Gonzales";
            representanteACrear.Cargo = "Gerente general";


            Assert.Catch<Exception>(delegate
            {
                representanteCreado = representanteDAO.Crear(representanteACrear);
            });
            
            // 2. Validar que se cree un representante correctamente (sin error)
            representanteACrear.NumeroDocumento = "46538292";
            representanteACrear.Grupo = grupo;
            representanteACrear.Cliente = cliente;

            Assert.DoesNotThrow(delegate
            {
                representanteCreado = representanteDAO.Crear(representanteACrear);
            });
            NuevoRepresentante = representanteCreado.CodigoRepresentante;
            // 3. Validar que el representante creado no sea nulo, tenga un código diferente a una cadena vacía y el cliente y el grupo sean los ingresados
           
           Assert.IsNotNull(representanteCreado);
           Assert.Greater(representanteCreado.CodigoRepresentante,0);
           Assert.AreEqual(representanteCreado.Cliente.CodigoCliente, cliente.CodigoCliente);
           Assert.AreEqual(representanteCreado.Grupo.CodigoGrupo, grupo.CodigoGrupo);
        }
        [Test]
        public void Test2_Obtener()
        {
            Representante representanteObtenido = null;
            // 1. Validar que se retorne nulo al obtener un representante inexistente
            Assert.DoesNotThrow(delegate
            {
                representanteObtenido = representanteDAO.Obtener(0);
            });
            Assert.IsNull(representanteObtenido);


            // 2. Validar que se obtenga el representante creado satisfactoriamente
            Assert.DoesNotThrow(delegate
            {
                representanteObtenido = representanteDAO.Obtener(representanteCreado.CodigoRepresentante);
            });
            Assert.IsNotNull(representanteObtenido);

            // 3. Validar que el numero de documento obtenido sea el creado anteriormente
            Assert.AreEqual(representanteObtenido.NumeroDocumento, "46538292");
        }

        [Test]
        public void Test3_Modificar()
        {
            Representante representanteAModificar = representanteDAO.Obtener(representanteCreado.CodigoRepresentante);
            representanteAModificar.TipoDocumento = "PSP";
            representanteAModificar.NumeroDocumento = null; // "38849949";
            representanteAModificar.Nombres = "Carmen";
            representanteAModificar.Apellidos = "Mendoza";
            representanteAModificar.Grupo = null;
            representanteAModificar.Cliente = null;

            Representante representanteModificado = null;

            // 1. Validar que ocurrar un error al intentar modificar el representante con un grupo y cliente nulo
            Assert.Catch<Exception>(delegate
            {
                representanteModificado = representanteDAO.Modificar(representanteAModificar);
            });

            // 2. Validar que se modifique correctamente el representante
            representanteAModificar.NumeroDocumento = "38849949";
            representanteAModificar.Grupo = grupo;
            representanteAModificar.Cliente = cliente;

            Assert.DoesNotThrow(delegate
            {
                representanteModificado = representanteDAO.Modificar(representanteAModificar);
            });


            // 3. Validar que el representante modificado no sea nulo, tenga el nombre, número de documento, el grupo y cliente indicados
  
            Assert.IsNotNull(representanteModificado);
            Assert.AreEqual(representanteAModificar.Nombres, representanteModificado.Nombres);
            Assert.AreEqual(representanteAModificar.NumeroDocumento, representanteModificado.NumeroDocumento);
            Assert.AreEqual(representanteAModificar.Grupo.CodigoGrupo, representanteModificado.Grupo.CodigoGrupo);
            Assert.AreEqual(representanteAModificar.Cliente.CodigoCliente, representanteModificado.Cliente.CodigoCliente);
                    }
        [Test]
        public void Test4_Eliminar()
        {
            Representante representanteAEliminar = representanteDAO.Obtener(representanteCreado.CodigoRepresentante);
            // 1. Validar que ocurre un error si se intenta eliminar un representante nulo
            Assert.Catch<Exception>(delegate
            {
                representanteDAO.Eliminar(null);
            });
            // 2. Validar que se elimina correctamente el representante creado
            Assert.DoesNotThrow(delegate
            {
                representanteDAO.Eliminar(representanteAEliminar);
            });
            // 3. Validar que luego de eliminado se retorne nulo al obtenerlo
            Representante representanteEliminado = representanteDAO.Obtener(representanteCreado.CodigoRepresentante);
            Assert.IsNull(representanteEliminado);

        }
        [Test]
        public void Test5_Listar()
        {
            representanteDAO.Crear(new Representante() { Cliente = clienteDAO.Obtener(1), TipoDocumento = "DNI", NumeroDocumento = "4527282", Nombres = "Alexandra", Apellidos = "Gonzales", Grupo = grupoDAO.Obtener(NuevoGrupo), Cargo = "Gerente General" });
            representanteDAO.Crear(new Representante() { Cliente = clienteDAO.Obtener(1), TipoDocumento = "DNI", NumeroDocumento = "29983332", Nombres = "Piero", Apellidos = "Marquez", Grupo = grupoDAO.Obtener(NuevoGrupo), Cargo = "Gerente General" });
            // 1. Validar que se listen los representantes existentes exitosamente
            ICollection<Representante> representantesExistentes = null;
            Assert.DoesNotThrow(delegate
            {
                representantesExistentes = representanteDAO.ListarTodos();
            });

            // 2. Validar que se retornen al menos los 2 representantes creados previamente
            Assert.GreaterOrEqual(representantesExistentes.Count, 2);

            // 3. Validar que cada representante obtenido tenga un Numero de documento no nulo
            foreach (Representante representante in representantesExistentes)
                Assert.IsNotNull(representante.NumeroDocumento);
        }

        [TestFixtureTearDown]
        public void FinalizarPruebas()
        {
            foreach (Representante representante in representanteDAO.ListarTodos())
                representanteDAO.Eliminar(representante);

            grupoDAO.Eliminar(grupo);
            clienteDAO.Eliminar(cliente);

            Persistencia.NH.NHibernateHelper.CerrarFabrica();
        }
         
    }
}